<?php

abstract class ControllerYeti implements ControllerInterfaceYeti {
    protected $namedClass, $model, $use_token;
    protected $before = Array(), $after = Array(), $template = Array();
    
    private $execMethod = TRUE, $loadedModel = Array(), $loadedLib = Array();
    
    const ALLOW_PRODUCTION = TRUE;
    
    public function __construct() {
        if(!preg_match('/(.*)ControllerYeti/i', get_class($this), $_namedClass)) {
            throw new ControllerYetiException('This controller not is valid');
            return NULL;
        }
        
        $this->namedClass = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '.\\1', $_namedClass[1]));
        
        if(!$this->model) {
            $this->model = $this->namedClass;
        }
        
        if(method_exists($this, '_access_control')) {
            
        }
    }
    
    protected function setLayout() {
        return Array();
    }
    
    protected function beforeFilter() {
        return Array();
    }
    
    protected function afterFilter() {
        return Array();
    }
    
    protected function doPost() {
        return;
    }
    
    protected function doPut() {
        return;
    }
    
    protected function doDelete() {
        return;
    }
    
    final protected function getExecMethod() {
        return $this->execMethod;
    }
    
    final protected function setExecMethod($execMethod) {
        $this->execMethod = $execMethod;
    }
    
    final public function executeTriggerBefore() {
        foreach($this->beforeFilter() as $func) {
            $method = array_shift($func);
            $this->executeFilter($method, $func);
        }
    }
    
    final public function executeTriggerAfter() {
        foreach($this->afterFilter() as $func) {
            $method = array_shift($func);
            $this->executeFilter($method, $func);
        }       
    }
    
    final private function executeFilter($func, $opts) {
        if(parent::normalizeOptionsIsExec($opts, $method)) {
            $this->$func();
        }
    }
    
    final protected function loadLib($lib, $overload = FALSE) {
        if(!self::$loadedLib[$lib] || $overload) {
            self::$loadedLib[$lib] = Yeti::factory("lib.{$lib}", 'controller');
        }
        
        return self::$loadedLib[$lib];
    }
    
    final protected function loadModel($model = NULL, $overload = FALSE) {
        if(!$model) {
            $model = $this->model;
        }
        
        if(!self::$loadedModel[$model] || $overload) {
            self::$loadedModel[$model] = Yeti::factory("model.{$model}");
        }
        
        return self::$loadedModel[$model];        
    }
}
